home *** CD-ROM | disk | FTP | other *** search
/ MacTech 1 to 12 / MacTech-vol-1-12.toast / Source / MacTech® Magazine / Volume 05 - 1989 / 05.09 Sep 89 / MacApp Code / Plot - Nelson / UPlot.p < prev   
Encoding:
Text File  |  1989-04-12  |  46.6 KB  |  1,849 lines  |  [TEXT/MPS ]

  1. {[a-,body+,h-,o=100,r+,rec+,t=4,u+,#+,j=20/57/1$,n+]}
  2. { The above is the official MacApp PasMat Style statement.
  3.   What you don’t use pasmat to make all your source code
  4.   conform to your company’s (or personal) standard for source
  5.   code style? }
  6.  
  7. {Copyright © 1986-1988 by Apple Computer, Inc. All rights reserved.}
  8. {Copyright © 1989 by Software Architects, Inc. All rights reserved.}
  9. {Portions Copyright © 1988 MacTutor All rights reserved.}
  10.  
  11. {[f-]}
  12. (*
  13.     This is a very small sample application which uses concepts and program fragments
  14.     presented in the February 1988 MacTutor Plot Article.
  15.     
  16.     By looking at this program you may be able to gain a better understanding of how to
  17.     cast a conventional program into the MacApp “Application Framework” or (Class structure
  18.     depending upon whose jargon you wish to use).
  19.     
  20.     In the tradition of MacApp it defines the basic three Class (object) overrides:
  21.     
  22.        TPlotApplication.DoMakeDocument    -- Launches the appropriate type of Document
  23.                                             object
  24.        TPlotDoc.DoMakeViews                 --  Launches the appropriate type of View
  25.                                             and window objects
  26.        TPlotDialog.Draw                    --  Calls it sub components to draw the
  27.                                                contents of a view
  28.             TPlotView                    --  To actually plot the thing
  29.             TSolveView                    --  To draw the solution text box
  30.             
  31.     In addition it defines commands unique to the plot program.
  32.     See the text of the accompaning article for detials.
  33.     
  34. *)
  35. {[f+]}
  36.  
  37. UNIT UPlot;
  38.  
  39. INTERFACE
  40.     USES
  41.         { • MacApp - this includes all of the things necessary from the MacApp Library }
  42.         UMacApp, 
  43.  
  44.         { • Building Blocks }
  45.         UDialog, UPrinting, UExtendedText,
  46.  
  47.         { • Implementation Use }
  48.         SANE, ToolUtils, Fonts, Resources, Script, PickerIntf, Packages;
  49.  
  50.     CONST
  51.  
  52.         kSignature            = 'Plot';        { Application signature}
  53.         kFileType            = 'PICT';        { File-type code used for document files
  54.                                                 created by this application}
  55.         kPlotDialog            = 1010;
  56.              
  57.         {  MacApp uses a very useful technique for seperating menu item numbering from
  58.            what you want done by chosing a menu item.  See MacApp manual pggs xxx-xx 
  59.            for full details.  Work is done in MacApp with commands.  Each command is 
  60.            usuallly assigned a unique number.  For example Save is 30 and SaveAs is 32.
  61.            Numbers belwo 1200 are reserved for MacApp.
  62.  
  63.            In this Application we have chosen a command numbering scheme that makes life
  64.            easy:
  65.             Application Commands= 1400
  66.             Font styles             = 2000
  67.             Font sizes          = 2100
  68.             Font just           = 2200
  69.             Font fonts          = 2300
  70.             Hierarchical Menus  = 2400
  71.             Plot colors         = 2500
  72.         }
  73.         
  74.             cPlotIt    = 1401;        { the command to cause a plot to happen }
  75.         
  76.         { Command numbers for typestyle attributes }
  77.             cPlainText            = 2001;
  78.             cBold                = 2002;
  79.             cItalic             = 2003;
  80.             cUnderline            = 2004;
  81.             cOutline            = 2005;
  82.             cShadow             = 2006;
  83.             cCondense            = 2007;
  84.             cExtend             = 2008;
  85.         
  86.         { Command numbers for font-size commands }
  87.             cSizeChange         = 2100;
  88.             cSizeBase            = 2100;
  89.             cSizeMin            = 2109;
  90.             cSizeMax            = 2124;
  91.             
  92.         { 2101-2197 reserved for font sizes 1-97 pts. }
  93.             cSizeGrow            = 2198;
  94.             cSizeShrink         = 2199;
  95.         
  96.         { Command numbers to cover other stylistic changes }
  97.             cJustChange         = 2200;
  98.             cJustLeft            = 2201;                            { Justification commands }
  99.             cJustCenter         = 2202;
  100.             cJustRight            = 2203;
  101.             
  102.             cFontChange         = 2300;
  103.         
  104.         { Command numbers for the hierarchial menu }
  105.             cStyle                = 2401;
  106.             cSize                = 2402;
  107.             cFont                = 2403;
  108.             cColor                = 2404;
  109.         
  110.         { Command numbers for changing colors }
  111.             cColorChange        = 2500;
  112.             cColorText            = 2501;
  113.             cColorBackground    = 2502;
  114.             cColorGraph            = 2503;
  115.             cColorAxis            = 2504;
  116.         
  117.         { Constant for amount to relative size text selection }
  118.             kRelSizeAmount        = 4;
  119.  
  120.         { Constants for the prompts string list }
  121.             kPromptsRsrcID        = 1001;
  122.             kColTextPrompt        = 1;
  123.             kColBackPrompt        = 2;
  124.             kColGraphPrompt        = 3;
  125.             kColAxisPrompt        = 4;
  126.         
  127.         { Menu numbers }
  128.         mFont                    = 10;        
  129.     
  130.         kHierDisplayedMBar        = 131;    { Menus displayed on hier. menu system }
  131.         kNonHierDisplayedMBar     = 128;    { Menus displayed on non-hier. system }
  132.         
  133.         kHierMenuOffset         = 1000; { Offset added to non-hier menu cmds to get }
  134.         kViewRsrcID             = 1005; { 'view' resource for default values }
  135.  
  136.         kBlackColor                = 33;    { for a Black forground }
  137.         
  138.         { PICT comments for our plot and text box }
  139.         
  140.         {selected MacDraw comments}
  141.             picDwgBeg         = 130;
  142.             picDwgEnd        = 131;
  143.             picGrpBeg         = 140;
  144.             picGrpEnd         = 141;
  145.             TextBegin         = 150;
  146.             TextEnd         = 151;
  147.             StringBegin        = 151;
  148.             StringEnd         = 153;
  149.             TextCenter         = 154;
  150.  
  151.         {postscript comments}
  152.             SetLineWidth     = 182;
  153.             PostScriptBegin = 190;
  154.             TextIsPostscript = 194;
  155.             PostScriptEnd     = 191;
  156.             
  157.         { The size of a MacDraw Header }
  158.             kHeaderSize     = 512;
  159.             
  160.     TYPE
  161.  
  162.         QuadraticType = (NotSolved,RealRoots,SingleSolution,ComplexRoot);
  163.         
  164.     (* remove this ???
  165.         PlotDocDiskInfo = RECORD
  166.             tempA : INTEGER;
  167.             tempB : INTEGER;
  168.             tempC : INTEGER;
  169.             END;
  170.     *)
  171.     
  172.         PlotSpecs    = RECORD                        {specifications of text display}
  173.             theTextFont:        Str255;
  174.             theFontNum:            INTEGER;
  175.             theTextFace:        Style;
  176.             theTextSize:        INTEGER;
  177.             theJustification:    INTEGER;            { text justification }
  178.             theTextColor:        RGBColor;            { text label color }
  179.             theGraphColor:        RGBColor;            { The color to draw the graph }
  180.             theAxisColor:        RGBColor;            { and our axes }
  181.             theBackColor:        RGBColor;            { Window's background color }
  182.             END;
  183.         PlotSpecsPtr        = ^PlotSpecs;
  184.         PlotSpecsHdl        = ^PlotSpecsPtr;
  185.  
  186.  
  187.     { Object Definitions }
  188.     {---------------------------------------------------}
  189.         TPlotApplication = OBJECT (TApplication)
  190.  
  191.             PROCEDURE TPlotApplication.IPlotApplication(itsMainFileType: OSType);
  192.             { Initializes the application and globals. }
  193.  
  194.             FUNCTION TPlotApplication.DoMakeDocument(itsCmdNumber: cmdNumber): TDocument;
  195.                 OVERRIDE;
  196.             { Launches a TPlotDocument }
  197.             
  198.             (*
  199.             FUNCTION TPlotApplication.MakeViewForAlienClipboard: TView; OVERRIDE;
  200.             *)
  201.             
  202.             PROCEDURE TPlotApplication.IdentifySoftware; OVERRIDE;
  203.             PROCEDURE TPlotApplication.Fields(PROCEDURE DoToField(fieldName: Str255;
  204.                                                 fieldAddr: Ptr;fieldType: INTEGER)); OVERRIDE;
  205.             
  206.             END;                                    { TPlotApplication }
  207.     
  208.     {---------------------------------------------------}
  209.         TPlotDoc        = OBJECT (TDocument)
  210.     
  211.             fPlotDialog    : TPlotDialog;
  212.             fPlotSpecs    : PlotSpecs;
  213.             fOldPlot    : PicHandle;
  214.             
  215.             faParam        : Real;
  216.             fbParam     : Real;
  217.             fcParam        : Real;
  218.                 { the coefficients to our quadratic equation }
  219.                 
  220.             fstepParam     : Real;
  221.             fxParam        : INTEGER;
  222.             fyParam     : INTEGER;
  223.                 { plot display parameters }
  224.                 
  225.             f1stRoot    : Real;
  226.             f2ndRoot    : Real;
  227.                 { the solutions to our quadratic }
  228.             
  229.             fRootType    : QuadraticType;
  230.                 
  231.             PROCEDURE TPlotDoc.IPlotDocument;
  232.                 { setup for the document to hold the plot }
  233.                 
  234.             PROCEDURE TPlotDoc.DoInitialState; OVERRIDE;
  235.                 { For new doc or revert setup an initial state }
  236.  
  237.             FUNCTION  TPlotDoc.DoMakePStyleCmd(itsStyle:PlotSpecsPtr; itsCmdNumber:CmdNumber): TPStyleCmd;
  238.                 { Generate a command to change the Look of a plot }
  239.                 
  240.             PROCEDURE TPlotDoc.DoMakeViews(forPrinting: BOOLEAN); OVERRIDE;
  241.                 { create all the views needed for the document }
  242.                 
  243.             PROCEDURE TPlotDoc.DoNeedDiskSpace(VAR dataForkBytes,
  244.                 rsrcForkBytes: LONGINT); OVERRIDE;
  245.                 { calculater how much disk space this document will need }
  246.     
  247.             PROCEDURE TPlotDoc.DoRead(aRefNum: INTEGER; rsrcExists,
  248.                 forPrinting: BOOLEAN); OVERRIDE;
  249.                 { read the data for this document }
  250.                 
  251.             PROCEDURE TPlotDoc.DoWrite(aRefNum: INTEGER; makingCopy: BOOLEAN); OVERRIDE;
  252.                 { write the data for this document }
  253.                 
  254.             FUNCTION TPlotDoc.DoMenuCommand(aCmdNumber: cmdNumber): TCommand; OVERRIDE;
  255.                 { given a Menu choice handle it or pass it on }
  256.                 
  257.             PROCEDURE TPlotDoc.DoSetupMenus; OVERRIDE;
  258.                 { setup the menus for the document }
  259.                 
  260.             PROCEDURE TPlotDoc.SolveQuadratic;
  261.                 { given the parameters of our document calculate a solution }
  262.  
  263.             PROCEDURE TPlotDoc.ChangeBackColor(newColor: RGBColor);
  264.  
  265.             {$IFC qDebug}
  266.             PROCEDURE TPlotDoc.Fields(PROCEDURE
  267.                                         DoToField(fieldName: Str255; fieldAddr: Ptr;
  268.                                                      fieldType: INTEGER)); OVERRIDE;
  269.             {$ENDC}
  270.     
  271.             END;                                    { TPlotDoc }
  272.     
  273.  
  274.         TPlotView        = OBJECT (TView)
  275.         
  276.             fPlotDoc        : TPlotDoc;
  277.             
  278.             PROCEDURE TPlotView.AddToPict(picRect:Rect);
  279.                 { Add to the pict we will draw on the screen or printed page }
  280.                 
  281.             PROCEDURE TPlotView.GetQDFrame(VAR frameRect:Rect);
  282.                 { A convenience routine }
  283.                 
  284.             PROCEDURE TPlotView.Resize(width, height: VCoordinate; invalidate: BOOLEAN); OVERRIDE
  285.                 { The design says the plot fills the window, therefore when we are
  286.                   resized we must invalidate ourselves}
  287.             END;
  288.             
  289.         TSolutionView = OBJECT (TView)
  290.  
  291.             fPlotDoc        : TPlotDoc;
  292.             fSolveRect        : Rect;
  293.             
  294.             PROCEDURE TSolutionView.AddToPict(picRect:Rect);
  295.                 { Add to the pict we will draw on the screen or printed page }
  296.             END;
  297.             
  298.             
  299.         TPlotDialog        = OBJECT (TDialogView)
  300.         
  301.             fPlotSize        : VPoint;
  302.             fPlotView        : TPlotView;
  303.             fSolutionView    : TSolutionView;
  304.             fPlotDoc        : TPlotDoc;
  305.             fPlotPICT         : PicHandle;
  306.  
  307.             FUNCTION  TPlotDialog.DoKeyCommand(ch: CHAR; aKeyCode: INTEGER;
  308.                                               VAR info: EventInfo): TCommand; OVERRIDE;
  309.     
  310.             FUNCTION  TPlotDialog.DoMenuCommand(aCmdNumber: CmdNumber):TCommand; OVERRIDE;
  311.  
  312.             PROCEDURE TPlotDialog.DismissDialog(dismisser: IDType;
  313.                                             flashDismisser: BOOLEAN); OVERRIDE;
  314.         
  315.             PROCEDURE TPlotDialog.Draw(area: Rect); OVERRIDE;
  316.             
  317.             PROCEDURE TPlotDialog.EachSubView(PROCEDURE DoToSubView(theSubView: TView)); OVERRIDE
  318.                         
  319.             PROCEDURE TPlotDialog.PlotNDrawPICT;
  320.             
  321.             PROCEDURE TPlotDialog.GetPlotValues;
  322.  
  323.             PROCEDURE TPlotDialog.DoSetupMenus; OVERRIDE;
  324.             
  325.             END;
  326.  
  327.         TPStyleCmd = OBJECT (TCommand)
  328.             fPlotDialog        : TPlotDialog;
  329.             fOldPlotSpecs     : PlotSpecs;
  330.             fNewPlotSpecs     : PlotSpecs;
  331.             
  332.             PROCEDURE TPStyleCmd.IPStyleCmd(itsPlotDialog:TPlotDialog; itsNewStyle:PlotSpecsPtr; itsCmdNumber: CmdNumber);
  333.  
  334.             { Initialize the command; if unsuccessful,
  335.                 signalled by Failure mechanism }
  336.  
  337.             PROCEDURE TPStyleCmd.DoIt;    OVERRIDE;
  338.             PROCEDURE TPStyleCmd.RedoIt;    OVERRIDE;
  339.             PROCEDURE TPStyleCmd.UndoIt;    OVERRIDE;
  340.             {
  341.             PROCEDURE TCommand.Commit;    OVERRIDE; 
  342.             }
  343.             END;
  344.  
  345.     VAR
  346.  
  347.         gDefaultSpecs:        PlotSpecs;
  348.         gMenuOfs:            INTEGER;                { a Menu Management Global }
  349.         gPromptString:        Str255;                    { a Convenience for fetching
  350.                                                       strings from a resource }
  351.  
  352. IMPLEMENTATION
  353. { I M P L E M E N T A T I O N }
  354. {---------------------------------------------------}
  355. {$S ARes}
  356.  
  357. FUNCTION GetPrompt(index: INTEGER): StringPtr;
  358.  
  359.     BEGIN
  360.     GetIndString(gPromptString, kPromptsRsrcID, index);
  361.     GetPrompt := @gPromptString;
  362.     END;
  363.  
  364.  
  365. FUNCTION Real2Str(aReal: Real; theDigits: INTEGER): Str255;         
  366.     VAR aStr : DecStr;
  367.         form : DecForm;        
  368.     BEGIN
  369.     form.style  := FixedDecimal;
  370.     form.digits := theDigits;
  371.     Num2Str(form,aReal,aStr);
  372.     
  373.     Real2Str := aStr;
  374.     END;
  375.  
  376.  
  377. {$IFC qDebug}
  378. {$IFC qTrace} {$D+} {$ENDC}
  379.  
  380. { In the final version of MacApp 2.0 there will some kind of
  381.     support for REAL numbers in text entry fields, for now
  382.     we use Calvins Cock’s code from the January ’89 Frameworks }
  383.     
  384. PROCEDURE MyFieldToString(theData: Ptr;
  385.                           fieldType: integer;
  386.                           VAR theString: str255);
  387.                                   
  388.     CONST
  389.         DecPrec = 2;  { Change this if you want more decimal precision }
  390.  
  391.    TYPE
  392.       TAlias              = RECORD
  393.          CASE integer OF
  394.             bReal, bSingle:
  395.                (asReal             : Real);
  396.             bDouble:
  397.                (asDouble           : Double);
  398.             bExtended:
  399.                (asExtended         : Extended);
  400.          END;
  401.  
  402.    VAR
  403.       alias              : ^TAlias;
  404.       aDecForm           : DecForm;
  405.       x                  : Extended;
  406.       NumStr             : DecStr;
  407.  
  408.    BEGIN
  409.       alias := Pointer(theData);
  410.       WITH alias^ DO
  411.          CASE fieldType OF
  412.             bReal, bSingle:
  413.                BEGIN
  414.                   aDecForm.style := FixedDecimal;
  415.                   aDecForm.digits := DecPrec;
  416.                   x := asReal;
  417.                   Num2Str(aDecForm, x, NumStr);
  418.                   theString := str255(NumStr);
  419.                END;
  420.             bDouble:
  421.                BEGIN
  422.                   aDecForm.style := FixedDecimal;
  423.                   aDecForm.digits := DecPrec;
  424.                   x := asDouble;
  425.                   Num2Str(aDecForm, x, NumStr);
  426.                   theString := str255(NumStr);
  427.                END;
  428.             bExtended:
  429.                BEGIN
  430.                   aDecForm.style := FixedDecimal;
  431.                   aDecForm.digits := DecPrec;
  432.                   x := asExtended;
  433.                   Num2Str(aDecForm, x, NumStr);
  434.                   theString := str255(NumStr);
  435.                END;
  436.             OTHERWISE StdFieldToString(theData, fieldType, theString);
  437.          END;
  438.    END;
  439.  
  440. {$IFC qTrace} {$D++} {$ENDC}
  441. {$ENDC qDebug}
  442.  
  443. {---------------------------------------------------}
  444. {$S AReadFile}
  445.  
  446. PROCEDURE ReadBytes(theRefNum: INTEGER; size: LONGINT; buffer: Ptr);
  447. { Utility for reading data from a file }
  448.  
  449.     BEGIN
  450.     FailOSErr(FSRead(theRefNum, size, buffer));
  451.     END;
  452.  
  453.  
  454. {---------------------------------------------------}
  455. {$S AWriteFile}
  456.  
  457. PROCEDURE WriteBytes(theRefNum: INTEGER; size: LONGINT; buffer: Ptr);
  458. { Utility for writing data to a file. }
  459.  
  460.     BEGIN
  461.     FailOSErr(FSWrite(theRefNum, size, buffer));
  462.     END;
  463.  
  464. {---------------------------------------------------}
  465. {$S AInit}
  466.  
  467. PROCEDURE TPlotApplication.IPlotApplication(itsMainFileType: OSType);
  468.     VAR
  469.         fontName:            Str255;
  470.         aTEView:            TTEView;
  471.  
  472.     BEGIN
  473.     
  474.     { qNeedsHierarchialMenus is a MacApp compile time flag you can 
  475.         set which will require the use of Heirarchical Menus }
  476.         
  477.     {$IFC NOT qNeedsHierarchialMenus}
  478.     IF NOT gConfiguration.hasHierarchicalMenus THEN
  479.         BEGIN
  480.         gMBarDisplayed := kNonHierDisplayedMBar;
  481.         gMenuOfs := 0;
  482.         END
  483.     ELSE
  484.     {$ENDC}
  485.         BEGIN
  486.         gMBarDisplayed := kHierDisplayedMBar;
  487.         gMenuOfs := kHierMenuOffset;
  488.         END;
  489.         
  490.     IApplication(itsMainFileType);
  491.     
  492.     { Do not setup the menus if we were started up with the
  493.         request to print }
  494.     IF NOT gFinderPrinting THEN
  495.         BEGIN
  496.         AddResMenu(GetMHandle(mFont), 'FONT');
  497.  
  498.         SetStyle(cBold, [bold]);
  499.         SetStyle(cUnderline, [underline]);
  500.         SetStyle(cItalic, [italic]);
  501.         SetStyle(cOutline, [outline]);
  502.         SetStyle(cShadow, [shadow]);
  503.         SetStyle(cCondense, [condense]);
  504.         SetStyle(cExtend, [extend]);
  505.         END;
  506.  
  507.  
  508.     { We have the Viewedit tool at our disposal, so why not use it
  509.     to create a useful resource to get our initial values from
  510.     instead of hard-wiring the defaults. The technique here is to
  511.     define a TTEView resource and use all those great fields that
  512.     you can setup with viewEdit as the defaults, then trash the TTEView
  513.     once all the work is done. }
  514.     
  515.     aTEView := TTEView(DoCreateViews(NIL, NIL, kViewRsrcID, gZeroVPt));
  516.     FailNIL(aTEView);
  517.     
  518.     GetFontName(aTEView.fTextStyle.tsFont, fontName);
  519.     WITH gDefaultSpecs, aTEView DO                { Set up initial text specs }
  520.         BEGIN
  521.         theTextFont := fontName;
  522.         theTextFace := fTextStyle.tsFace;
  523.         theTextSize := fTextStyle.tsSize;
  524.         theTextColor := fTextStyle.tsColor;
  525.         theJustification := fJustification;
  526.         theBackColor := gRGBWhite;
  527.         END;
  528.     aTEView.Free;
  529.  
  530.     { Until MacApp 2.0 debug and ViewTemplates support REALs this
  531.       is our work around from Calvin Cock’s January ’89 MapApp
  532.       Frameworks article. }
  533.     gFieldToStrRtn := @MyFieldToString;
  534.  
  535.     END;
  536.  
  537.  
  538. {---------------------------------------------------}
  539. {$IFC qDebug}
  540. {$S ADebug}
  541.  
  542. PROCEDURE TPlotApplication.IdentifySoftware;
  543.  
  544.     BEGIN
  545.     WriteLn('Plot Source date: 31 Jan 89; Compiled: ', COMPDATE, ' @ ', COMPTIME);
  546.     INHERITED IdentifySoftware;
  547.     END;
  548.  
  549.  
  550.  
  551. PROCEDURE TPlotApplication.Fields(PROCEDURE DoToField(fieldName: Str255; fieldAddr: Ptr;
  552.                                                    fieldType: INTEGER)); OVERRIDE;
  553.     BEGIN
  554.     WITH gDefaultSpecs DO
  555.         BEGIN
  556.         DoToField('  Font', @theTextFont, bFontName);
  557.         DoToField('  Face', @theTextFace, bStyle);
  558.         DoToField('  Size', @theTextSize, bInteger);
  559.         END;
  560.     END;
  561. {$ENDC}
  562.  
  563.  
  564. {************************************************************************}
  565. {  T P l o t D o c u m e n t           }
  566. {************************************************************************}
  567.  
  568. {---------------------------------------------------}
  569. {$S AOpen}
  570.  
  571. PROCEDURE TPlotDoc.IPlotDocument;
  572.  
  573.     VAR
  574.         aRect:                Rect;
  575.  
  576.     BEGIN
  577.     IDocument(kFileType, kSignature, kUsesDataFork, NOT kUsesRsrcFork, NOT kDataOpen,
  578.               NOT kRsrcOpen);
  579.  
  580.     fOldPlot := NIL;
  581.     END;
  582.  
  583. {------------------------------------------------------------------------------}
  584. {$S AOpen}
  585.  
  586. FUNCTION TPlotApplication.DoMakeDocument(itsCmdNumber: cmdNumber): TDocument;
  587.  
  588.     VAR
  589.         aPlotDocument:        TPlotDoc;
  590.         dimensions:         Rect;
  591.  
  592.     BEGIN
  593.     { Allocate and initialize the document}
  594.     NEW(aPlotDocument);
  595.     FailNIL(aPlotDocument);
  596.     aPlotDocument.IPlotDocument;
  597.     DoMakeDocument := aPlotDocument;
  598.     END;
  599.  
  600. {------------------------------------------------------------------------------}
  601. {$S AOpen}
  602.  
  603. PROCEDURE TPlotDoc.DoInitialState; OVERRIDE;
  604.  
  605.     BEGIN
  606.     { when reverting to an old copy of a document we need to reset to some
  607.       reasonable values }
  608.       
  609.     fPlotSpecs  := gDefaultSpecs;
  610.     fOldPlot := NIL;
  611.     END;
  612.  
  613. {---------------------------------------------------}
  614. FUNCTION  TPlotDoc.DoMakePStyleCmd(itsStyle:PlotSpecsPtr; itsCmdNumber:CmdNumber): TPStyleCmd ;
  615.     VAR
  616.         aPStyleCmd:    TPStyleCmd;
  617.         aPlotDialog: TPlotDialog;
  618.         
  619.     BEGIN
  620.     New(aPStyleCmd);
  621.     FailNIL(aPStyleCmd);
  622.     aPlotDialog := fPlotDialog;
  623.     aPStyleCmd.IPStyleCmd(aPlotDialog, itsStyle, itsCmdNumber);
  624.     DoMakePStyleCmd := aPStyleCmd;
  625.     END;
  626.     
  627.     
  628. {---------------------------------------------------}
  629. {$S AOpen}
  630.  
  631. PROCEDURE TPlotDoc.DoMakeViews(forPrinting: BOOLEAN);
  632.  
  633.     VAR
  634.         aWindow:            TWindow;
  635.         aPlotDialog:        TPlotDialog;
  636.         aPlotView:            TPlotView;
  637.         aTEView:            TTEView;
  638.         aSolutionView:        TSolutionView;
  639.         aCluster:            TCluster;
  640.         aPrintHandler:        TStdPrintHandler;
  641.         anExtendedText:        TExtendedText;
  642.         aRect:                Rect;
  643.  
  644.     BEGIN
  645.     { We want to  dynamically call these in exisitance.  Do a New()
  646.       call for each object type, so the linker doesn't strip them out. }
  647.     IF gCreateWithTemplates THEN    
  648.         BEGIN                        
  649.         New(aPlotDialog);
  650.         New(aPlotView);
  651.         New(aTEView);                    
  652.         New(aSolutionView);
  653.         New(aCluster);
  654.         New(anExtendedText);
  655.         END;
  656.  
  657.     { we will now ceate and connect up all the view and document variables }
  658.     
  659.     aWindow := NewTemplateWindow(kPlotDialog, SELF);
  660.         { bring our plot window into exisitance }
  661.         
  662.     aPlotDialog := TPlotDialog(aWindow.FindSubView('DLOG'));
  663.     FailNIL(aPlotDialog);
  664.         { find the dialog portions and make certian we have it }
  665.  
  666.     fPlotDialog := aPlotDialog;
  667.         { save this away for late when we need to easily find the dialog }
  668.         
  669.     aPlotDialog.fPlotDoc := SELF;
  670.         { and of course we need to cross refer so tell the plotdialog who its doc is }
  671.         
  672.     IF (fOldPlot <> NIL)  | (GetHandleSize(Handle(fOldPlot)) > 0 ) THEN
  673.         aPlotDialog.fPlotPICT := fOldPlot
  674.         { If the document has an old plot PICT display it }
  675.     ELSE
  676.         aPlotDialog.GetPlotValues;
  677.         { Use the values from the resource to generate the first plot }
  678.  
  679.         { Find the PlotView and make some connections to our PlotDocument }
  680.     aPlotView := TPlotView(aWindow.FindSubView('plot'));
  681.     FailNIL(aPlotView);
  682.     aPlotView.fPlotDoc := SELF;
  683.     aPlotDialog.fPlotView := aPlotView;
  684.     aPlotDialog.fPlotPICT := NIL;
  685.     aPlotDialog.fPlotSize := aPlotView.fSize;
  686.  
  687.         { Find the SolutionView and make some connections to our PlotDocument }
  688.     aSolutionView := TSolutionView(aWindow.FindSubView('qslv'));
  689.     FailNIL(aSolutionView);
  690.     aSolutionView.fPlotDoc := SELF;
  691.     aPlotDialog.fSolutionView := aSolutionView;
  692.     
  693.         { while we are at it, retrieve the rectangle size we will use to display in }
  694.     SetRect(aRect,0,0,aSolutionView.fSize.h,aSolutionView.fSize.v);
  695.     aSolutionView.fSolveRect := aRect;
  696.     
  697.         { we want to limit the minimum size this window can be so… 
  698.           use the size of our clusters to determine the minimum}
  699.     aCluster:= TCluster(aWindow.FindSubView('Ccof'));
  700.     aWindow.fResizeLimits.top := aCluster.fSize.v * 2;
  701.     aWindow.fResizeLimits.left := aCluster.fSize.h * 3;
  702.     aCluster:= TCluster(aWindow.FindSubView('Cdsp'));
  703.     aWindow.fResizeLimits.top := aWindow.fResizeLimits.top + aCluster.fSize.v;
  704.  
  705.     NEW(aPrintHandler);
  706.     FailNIL(aPrintHandler);
  707.     aPrintHandler.IStdPrintHandler(SELF,            { its document }
  708.                                    aPlotDialog,        { its view }
  709.                                    FALSE,            { does not have square dots }
  710.                                    TRUE,            { horzontal page size is fixed }
  711.                                    FALSE);            { vertical page size is variable (could be
  712.                                                      set to true on non-style TE systems) }
  713.     aPrintHandler.fMinimalMargins := FALSE;
  714.     
  715.     END;
  716.  
  717. {---------------------------------------------------}
  718. {$S ASelCommand}
  719.  
  720. FUNCTION TPlotDoc.DoMenuCommand(aCmdNumber: CmdNumber): TCommand; OVERRIDE;
  721.  
  722.     VAR
  723.         aName:                Str255;
  724.         menu:                INTEGER;
  725.         item:                INTEGER;
  726.         newStyle:            PlotSpecs;
  727.  
  728.     {--------------------------------------------------------------}
  729.  
  730.     PROCEDURE DoSizeChange(base: CmdNumber);
  731.  
  732.         BEGIN
  733.         newStyle.theTextSize := aCmdNumber - base;
  734.         DoMenuCommand := DoMakePStyleCmd(@newStyle, cSizeChange);
  735.         END;
  736.  
  737.     {--------------------------------------------------------------}
  738.  
  739.     PROCEDURE DoRelSizeChange(amount: INTEGER);
  740.  
  741.         BEGIN
  742.         WITH newStyle DO
  743.             theTextSize := theTextSize + amount;
  744.         DoMenuCommand := DoMakePStyleCmd(@newStyle, cSizeChange);
  745.         END;
  746.  
  747.     {--------------------------------------------------------------}
  748.  
  749.     PROCEDURE DoFontChange;
  750.  
  751.         BEGIN
  752.         GetItem(GetMHandle(menu), item, newStyle.theTextFont);
  753.         GetFNum(aName, newStyle.theFontNum);
  754.         DoMenuCommand := DoMakePStyleCmd(@newStyle, cFontChange);
  755.         END;
  756.  
  757.     {--------------------------------------------------------------}
  758.  
  759.     PROCEDURE DoColTextChange;
  760.  
  761.         VAR
  762.             aColor:             RGBColor;
  763.  
  764.         BEGIN
  765.         aColor := fPlotSpecs.theTextColor;
  766.         IF GetColor(Point($00400040), GetPrompt(kColTextPrompt)^, aColor, newStyle.theTextColor) THEN
  767.             DoMenuCommand := DoMakePStyleCmd(@newStyle, cColorText);
  768.         END;
  769.  
  770.     {--------------------------------------------------------------}
  771.  
  772.     PROCEDURE DoColGraphChange;
  773.  
  774.         VAR
  775.             aColor:             RGBColor;
  776.  
  777.         BEGIN
  778.         aColor := fPlotSpecs.theGraphColor;
  779.         IF GetColor(Point($00400040), GetPrompt(kColGraphPrompt)^, aColor, newStyle.theGraphColor) THEN
  780.             DoMenuCommand := DoMakePStyleCmd(@newStyle, cColorGraph);
  781.         END;
  782.  
  783.     {--------------------------------------------------------------}
  784.  
  785.     PROCEDURE DoColAxisChange;
  786.  
  787.         VAR
  788.             aColor:             RGBColor;
  789.  
  790.         BEGIN
  791.         aColor := fPlotSpecs.theAxisColor;
  792.         IF GetColor(Point($00400040), GetPrompt(kColAxisPrompt)^, aColor, newStyle.theAxisColor) THEN
  793.             DoMenuCommand := DoMakePStyleCmd(@newStyle, cColorAxis);
  794.         END;
  795.  
  796.     {--------------------------------------------------------------}
  797.  
  798.     PROCEDURE DoColBackChange;
  799.  
  800.         VAR
  801.             aColor:             RGBColor;
  802.  
  803.         BEGIN
  804.         aColor := fPlotSpecs.theBackColor;
  805.         IF GetColor(Point($00400040), GetPrompt(kColBackPrompt)^, aColor, newStyle.theBackColor) THEN
  806.             BEGIN
  807.             DoMenuCommand := DoMakePStyleCmd(@newStyle, cColorBackGround);
  808.             END;
  809.         END;
  810.  
  811.     {--------------------------------------------------------------}
  812.  
  813.     PROCEDURE DoJustChange;
  814.  
  815.         VAR
  816.             newJust:            INTEGER;
  817.         BEGIN
  818.         CASE aCmdNumber OF
  819.             cJustLeft:
  820.                 newJust := teJustLeft;
  821.             cJustCenter:
  822.                 newJust := teJustCenter;
  823.             cJustRight:
  824.                 newJust := teJustRight;
  825.         END;
  826.         newStyle.theJustification := newJust;
  827.         DoMenuCommand := DoMakePStyleCmd(@newStyle, aCmdNumber);
  828.         END;
  829.  
  830.     {--------------------------------------------------------------}
  831.  
  832.     PROCEDURE DoPlainChange;
  833.  
  834.         BEGIN
  835.         newStyle.theTextFace := [];
  836.         DoMenuCommand := DoMakePStyleCmd(@newStyle, cStyleChange);
  837.         END;
  838.  
  839.     {--------------------------------------------------------------}
  840.  
  841.     PROCEDURE DoStyleChange;
  842.         VAR
  843.             newFace : Style;
  844.             
  845.         BEGIN
  846.         WITH newStyle DO
  847.             BEGIN
  848.             CASE aCmdNumber OF
  849.                 cBold:
  850.                     newFace := [bold];
  851.                 cItalic:
  852.                     newFace := [italic];
  853.                 cUnderline:
  854.                     newFace := [underline];
  855.                 cOutline:
  856.                     newFace := [outline];
  857.                 cShadow:
  858.                     newFace := [shadow];
  859.                 cCondense:
  860.                     newFace := [condense];
  861.                 cExtend:
  862.                     newFace := [extend];
  863.             END;
  864.             IF newFace * theTextFace = newFace THEN
  865.                 theTextFace := theTextFace - newFace
  866.             ELSE
  867.                 theTextFace := theTextFace + newFace;
  868.             END;
  869.         DoMenuCommand := DoMakePStyleCmd(@newStyle, cStyleChange);
  870.         END;
  871.  
  872.  
  873.     {--------------------------------------------------------------}
  874.  
  875.     BEGIN                                                { DoMenuCommand }
  876.     DoMenuCommand := gNoChanges;
  877.  
  878.     newStyle := fPlotSPecs;
  879.     
  880.     CmdToMenuItem(aCmdNumber, menu, item);
  881.  
  882.     IF menu = mFont THEN
  883.         DoFontChange
  884.     ELSE
  885.         CASE aCmdNumber OF
  886.             cSizeMin..cSizeMax:
  887.                 DoSizeChange(cSizeBase);
  888.  
  889.             cSizeGrow:
  890.                 DoRelSizeChange(kRelSizeAmount);
  891.  
  892.             cSizeShrink:
  893.                 DoRelSizeChange( - kRelSizeAmount);
  894.  
  895.             cJustLeft..cJustRight:
  896.                 DoJustChange;
  897.  
  898.             cPlainText:
  899.                 DoPlainChange;
  900.  
  901.             cBold..cExtend:
  902.                 DoStyleChange;
  903.  
  904.             cColorText:
  905.                 DoColTextChange;
  906.  
  907.             cColorGraph:
  908.                 DoColGraphChange;
  909.  
  910.             cColorAxis:
  911.                 DoColAxisChange;
  912.  
  913.             cColorBackground:
  914.                 DoColBackChange;
  915.  
  916.             OTHERWISE
  917.                 DoMenuCommand := INHERITED DoMenuCommand(aCmdNumber);
  918.         END;
  919.     END;
  920.  
  921.  
  922. {---------------------------------------------------}
  923. {$S ARes}
  924.  
  925. PROCEDURE TPlotDoc.DoSetupMenus; OVERRIDE;
  926.  
  927.     VAR
  928.         hasColor:            BOOLEAN;
  929.         hasStyle:            BOOLEAN;
  930.         checkPlain:         BOOLEAN;
  931.         checkSize:            BOOLEAN;
  932.         checkFont:            BOOLEAN;
  933.         specChange:         BOOLEAN;
  934.         just:                INTEGER;
  935.         item:                INTEGER;
  936.         fnt:                INTEGER;
  937.         c:                    INTEGER;
  938.         aMode:                INTEGER;
  939.         aFace:                Style;
  940.         aMenuHandle:        MenuHandle;
  941.         aName:                Str255;
  942.         aStyle:             TextStyle;
  943.         theFont:            INTEGER;
  944.         aStr255:            Str255;
  945.  
  946.     BEGIN
  947.     INHERITED DoSetupMenus;
  948.  
  949.     hasColor := gConfiguration.hasColorQD;
  950.     hasStyle := gConfiguration.hasStyleTextEdit;
  951.  
  952.     aStr255 := fPlotSpecs.theTextFont;
  953.     GetFNum(aStr255, aStyle.tsFont);
  954.     WITH aStyle, fPlotSpecs DO
  955.         BEGIN
  956.         tsFace := theTextFace;
  957.         tsSize := theTextSize;
  958.         tsColor := theTextColor;
  959.         END;
  960.     checkPlain := aStyle.tsFace = [];
  961.     checkFont := TRUE;
  962.  
  963.     aMenuHandle := GetMHandle(mFont);
  964.  
  965.     GetFontName(aStyle.tsFont, aName);                    { Get real font number in case tsFont is }
  966.     GetFNum(aName, theFont);                            { …the system or application font. }
  967.     FOR item := 1 TO CountMItems(aMenuHandle) DO
  968.         BEGIN
  969.   { There can be more than 31 menu entries with scrolling menus, but trying to enable
  970.    an item with number > 31 is bad news.  If the menu itself is enabled (which it
  971.    will be in MacApp if any of the first 31 items is enabled), then the extras
  972.    will always be enabled. }
  973.         IF item <= 31 THEN
  974.             EnableItem(aMenuHandle, item);
  975.         IF checkFont THEN
  976.             BEGIN
  977.             GetItem(aMenuHandle, item, aName);
  978.             GetFNum(aName, fnt);
  979.             CheckItem(aMenuHandle, item, fnt = theFont);
  980.             END;
  981.         END;
  982.  
  983.     just := fPlotSpecs.theJustification;                 { Enable justification related menu items }
  984.     EnableCheck(cJustLeft, TRUE, (just = teJustLeft));
  985.     EnableCheck(cJustCenter, TRUE, (just = teJustCenter));
  986.     EnableCheck(cJustRight, TRUE, (just = teJustRight));
  987.  
  988.     {$IFC NOT qNeedsHierarchialMenus}
  989.     IF gConfiguration.hasHierarchicalMenus THEN
  990.     {$ENDC}
  991.         BEGIN
  992.         Enable(cStyle, TRUE);                            { Enable sub-menus }
  993.         Enable(cSize, TRUE);
  994.         Enable(cFont, TRUE);
  995.         Enable(cColor, hasColor);
  996.         END;
  997.  
  998.     aFace := aStyle.tsFace;
  999.     EnableCheck(cPlainText, TRUE, checkPlain);            { Enable normal Style menu items }
  1000.     EnableCheck(cBold, TRUE, bold IN aFace);
  1001.     EnableCheck(cItalic, TRUE, italic IN aFace);
  1002.     EnableCheck(cUnderline, TRUE, underline IN aFace);
  1003.     EnableCheck(cOutline, TRUE, outline IN aFace);
  1004.     EnableCheck(cShadow, TRUE, shadow IN aFace);
  1005.     EnableCheck(cCondense, TRUE, condense IN aFace);
  1006.     EnableCheck(cExtend, TRUE, extend IN aFace);
  1007.  
  1008.     FOR c := cSizeMin TO cSizeMax DO
  1009.         BEGIN
  1010.         IF hasStyle THEN
  1011.             checkSize := FALSE
  1012.         ELSE
  1013.             checkSize := (c - cSizeBase) = aStyle.tsSize;
  1014.         EnableCheck(c, TRUE, checkSize);
  1015.         
  1016.         IF ((NOT hasStyle) |                        { If the record isn't styled, or }
  1017.            RealFont(aStyle.tsFont,c-cSizeBase))        { the size is a real one }
  1018.             THEN aFace := [outline]                    { …then we outline it }
  1019.         ELSE
  1020.             aFace := [];
  1021.         SetStyle(c, aFace);
  1022.         END;
  1023.  
  1024.     Enable(cSizeGrow, TRUE);
  1025.     Enable(cSizeShrink, TRUE);
  1026.  
  1027.     Enable(cColorText, hasColor);
  1028.     Enable(cColorBackground, hasColor);
  1029.     Enable(cColorGraph, hasColor);
  1030.     Enable(cColorAxis, hasColor);
  1031.  
  1032.     END;
  1033.  
  1034. {---------------------------------------------------}
  1035. {$S AWriteFile}
  1036.  
  1037. PROCEDURE TPlotDoc.DoNeedDiskSpace(VAR dataForkBytes, rsrcForkBytes: LONGINT);
  1038.  
  1039.     VAR
  1040.         r:                    Rect;
  1041.  
  1042.     BEGIN
  1043.     
  1044.     { In other MacApp Samples we would normally get the Print record
  1045.        space requirements  by doing:
  1046.        
  1047.         INHERITED DoNeedDiskSpace(dataForkBytes, rsrcForkBytes);
  1048.     
  1049.       BUT seeing as we are trying to imitate a MacDraw File we will just do 
  1050.       our size calculation }
  1051.  
  1052.     dataForkBytes := kHeaderSize { for std MacDraw Header }
  1053.                      + GetHandleSize(Handle(fPlotDialog.fPlotPICT));
  1054.                      
  1055.     { For now we will write only the PICT Handle in the future we
  1056.       might want to write the PlotSpecs and other parameters to the
  1057.       resource fork of the file }
  1058.     rsrcForkBytes := 0;
  1059.     
  1060.     END;
  1061.  
  1062. {---------------------------------------------------}
  1063. {$S AReadFile}
  1064.  
  1065. PROCEDURE TPlotDoc.DoRead(aRefNum: INTEGER; rsrcExists, forPrinting: BOOLEAN);
  1066.  
  1067.     VAR
  1068.         fi:         FailInfo;
  1069.         aPICTSize:    LONGINT;
  1070.         aPICTHandle:Handle;
  1071.         
  1072.     PROCEDURE SkipDocHeaderInfo;
  1073.  
  1074.         BEGIN
  1075.             { skip the dummy header }
  1076.             FailOSErr(SetFPos(aRefNum,fsFromStart,kHeaderSize));        
  1077.         END;
  1078.  
  1079.     PROCEDURE HdlReadFailure(error: OSErr; message: LONGINT);
  1080.  
  1081.         BEGIN
  1082.         { We ran into trouble reading the data for now do nothing}
  1083.         END;
  1084.  
  1085.     BEGIN
  1086.     CatchFailures(fi, HdlReadFailure);
  1087.     
  1088.     { Normally, we would ask our ancestors to read in their data by:
  1089.         INHERITED DoRead(aRefNum, rsrcExists, forPrinting);
  1090.       but we are imitating a MacDraw Doc and have to behave like one}
  1091.  
  1092.     SkipDocHeaderInfo;
  1093.     
  1094.     IF fOldPlot <> NIL THEN
  1095.         DisposHandle(Handle(fOldPlot));
  1096.     
  1097.     FailOSErr(GetEOF(aRefNum,aPICTSize));
  1098.     aPICTSize := aPICTSize - kHeaderSize;
  1099.     aPICTHandle := NewHandle(aPICTSize);
  1100.     
  1101.     HLock(aPICTHandle);
  1102.     ReadBytes(aRefNum, aPICTSize, aPICTHandle^);
  1103.     HUnLock(aPICTHandle);
  1104.  
  1105.     fOldPlot := PicHandle(aPICTHandle);
  1106.     
  1107.     Success(fi);
  1108.     END;
  1109.  
  1110. {---------------------------------------------------}
  1111. {$S AWriteFile}
  1112.  
  1113. PROCEDURE TPlotDoc.DoWrite(aRefNum: INTEGER; makingCopy: BOOLEAN);
  1114.  
  1115.     PROCEDURE WriteHeaderInfo;
  1116.  
  1117.         VAR
  1118.             aPtr:         Ptr;
  1119.  
  1120.         BEGIN
  1121.             aPtr := NewPtrClear(kHeaderSize);
  1122.             FailNil(aPtr);
  1123.             WriteBytes(aRefNum, kHeaderSize, aPtr);
  1124.             DisposPtr(aPtr);
  1125.         END;
  1126.  
  1127.     PROCEDURE WritePlotInfo;
  1128.         VAR
  1129.             aPICTHandle : Handle;
  1130.             aPICTSize    : LONGINT;
  1131.         BEGIN
  1132.             aPICTHandle := Handle(fPlotDialog.fPlotPICT);
  1133.             aPICTSize := GetHandleSize(aPICTHandle);
  1134.             
  1135.             HLock(aPICTHandle);
  1136.             WriteBytes(aRefNum, aPICTSize, aPICTHandle^);
  1137.             HUnLock(aPICTHandle);
  1138.         END;
  1139.  
  1140.  
  1141.     BEGIN
  1142.         WriteHeaderInfo;
  1143.         WritePlotInfo
  1144.     END;
  1145.  
  1146. {---------------------------------------------------}
  1147. {$S ARes}
  1148.     PROCEDURE TPlotDoc.SolveQuadratic;
  1149.         VAR
  1150.             a,b,c,check : real;
  1151.             
  1152.         FUNCTION PositiveCalc (a, b, check : real) : real;
  1153.             BEGIN
  1154.             PositiveCalc := (-b + sqrt(check)) / (2 * a);
  1155.             END;
  1156.     
  1157.         FUNCTION NegativeCalc (a, b, check : real) : real;
  1158.             BEGIN
  1159.             NegativeCalc := (-b - sqrt(check)) / (2 * a);
  1160.             END;
  1161.     
  1162.     BEGIN
  1163.         a := faParam;
  1164.         b := fbParam;
  1165.         c := fcParam;
  1166.         
  1167.         check := (b * b) - (4 * a * c);
  1168.         
  1169.         IF check = 0 THEN         { we have a double root (same place twice) }
  1170.             BEGIN
  1171.                 fRootType := SingleSolution;
  1172.                 f1stRoot := PositiveCalc(a, b, check);
  1173.                 f2ndRoot := f1stRoot;
  1174.             END
  1175.             
  1176.         ELSE IF check > 0 THEN     { we have a pair of “real” x axis crossings }
  1177.             BEGIN
  1178.                 fRootType := RealRoots;
  1179.                 f1stRoot := PositiveCalc(a, b, check);
  1180.                 f2ndRoot := NegativeCalc(a, b, check);
  1181.             END
  1182.         
  1183.         ELSE IF check < 0 THEN { the roots are represented by a complex number }
  1184.             BEGIN
  1185.                 fRootType := ComplexRoot;
  1186.                 check := -check;
  1187.                 f1stRoot := PositiveCalc(a, b, check);
  1188.                 f2ndRoot := NegativeCalc(a, b, check);
  1189.             END;
  1190.     END;
  1191.  
  1192. {---------------------------------------------------}
  1193. {$S ANonRes}
  1194.  
  1195. PROCEDURE TPlotDoc.ChangeBackColor(newColor: RGBColor);
  1196.  
  1197.     VAR
  1198.         oldPort:            GrafPtr;
  1199.         itsWindow:            TWindow;
  1200.  
  1201.     BEGIN
  1202.     itsWindow := TView(fPlotDialog).GetWindow;
  1203.     IF itsWindow <> NIL THEN
  1204.         BEGIN
  1205.         GetPort(oldPort);
  1206.         SetPort(itsWindow.fWMgrWindow);
  1207.         RGBBackColor(newColor);
  1208.         itsWindow.ForceRedraw;
  1209.         SetPort(oldPort);
  1210.         END;
  1211.     END;
  1212.  
  1213. {---------------------------------------------------}
  1214. {$IFC qDebug}
  1215. {$S AFields}
  1216.  
  1217. PROCEDURE TPlotDoc.Fields(PROCEDURE DoToField(fieldName: Str255; fieldAddr: Ptr;
  1218.                                                    fieldType: INTEGER)); OVERRIDE;
  1219.     VAR
  1220.         aStr : DecStr;
  1221.         form : DecForm;
  1222.         aReal: Real;
  1223.         
  1224.     BEGIN
  1225.     
  1226.     form.style := FloatDecimal;
  1227.     form.digits := 6;
  1228.     
  1229.     DoToField('TPlotDoc', NIL, bClass);
  1230.     aReal := faParam;
  1231.     Num2Str(form,aReal,aStr);
  1232.     DoToField('faParam', @aStr, bString);
  1233.  
  1234.     aReal := fbParam;
  1235.     Num2Str(form,aReal,aStr);
  1236.     DoToField('fbParam', @aStr, bString);
  1237.  
  1238.     aReal := fcParam;
  1239.     Num2Str(form,aReal,aStr);
  1240.     DoToField('fcParam', @aStr, bString);
  1241.  
  1242.     aReal := fstepParam;
  1243.     Num2Str(form,aReal,aStr);
  1244.     DoToField('fstepParam', @aStr, bString);
  1245.     DoToField('fxParam', @fxParam, bInteger);
  1246.     DoToField('fyParam', @fyParam, bInteger);
  1247.     
  1248.     DoToField('  Font', @fPlotSpecs.theTextFont, bFontName);
  1249.     DoToField('  Face', @fPlotSpecs.theTextFace, bStyle);
  1250.     DoToField('  Size', @fPlotSpecs.theTextSize, bInteger);
  1251.         
  1252.     INHERITED Fields(DoToField);
  1253.     END;
  1254. {$ENDC}
  1255.  
  1256.  
  1257. {******************************************************************************************}
  1258. {  T P l o t D i a l o g                 }
  1259. {******************************************************************************************}
  1260. {$S }
  1261.  
  1262. PROCEDURE TPlotDialog.DismissDialog(dismisser: IDType; flashDismisser: BOOLEAN); OVERRIDE;
  1263.  
  1264.     BEGIN
  1265.     INHERITED DismissDialog(dismisser, flashDismisser);
  1266.     END;
  1267.  
  1268.  
  1269. {---------------------------------------------------}
  1270. FUNCTION TPlotDialog.DoKeyCommand(ch: CHAR; aKeyCode: INTEGER;
  1271.                                  VAR info: EventInfo): TCommand; OVERRIDE;
  1272.     BEGIN
  1273.     { If Enter is pressed, assume we have new parameters
  1274.         and a new plot to create. }
  1275.     IF (ch = chEnter) THEN
  1276.         BEGIN
  1277.         PlotNDrawPICT;                { we have everything, lets DOIT! }
  1278.         DoKeyCommand := gNoChanges;    { We did all the work no reason to
  1279.                                       generate a command}
  1280.         END
  1281.     ELSE
  1282.         DoKeyCommand := INHERITED DoKeyCommand(ch, aKeyCode, info);
  1283. END;
  1284.  
  1285.  
  1286. {---------------------------------------------------}
  1287. FUNCTION TPlotDialog.DoMenuCommand(aCmdNumber: CmdNumber): TCommand; OVERRIDE;
  1288.  
  1289.     BEGIN
  1290.     { Plot Menu Command was chosen so create the plot. }
  1291.     IF (aCmdNumber = cPlotIt) THEN
  1292.         BEGIN
  1293.         PlotNDrawPICT;                 { we have everything, lets DOIT! }
  1294.         DoMenuCommand := gNoChanges; { We did all the work no reason to
  1295.                                        generate a command}
  1296.         END
  1297.     ELSE
  1298.         DoMenuCommand := INHERITED DoMenuCommand(aCmdNumber);
  1299. END;
  1300.  
  1301.  
  1302. {---------------------------------------------------}
  1303. PROCEDURE TPlotDialog.DoSetupMenus; OVERRIDE;
  1304.  
  1305. BEGIN
  1306.     Enable(cPlotIt, TRUE);
  1307.     INHERITED DoSetupMenus;
  1308. END;
  1309.  
  1310.  
  1311. {---------------------------------------------------}
  1312. PROCEDURE TPlotDialog.Draw(area: Rect); OVERRIDE;
  1313.     VAR
  1314.         plotRect    : Rect;
  1315.         dontCare    : BOOLEAN;
  1316.         
  1317.     BEGIN
  1318.         { dontCare := SELF.Focus; }
  1319.         dontCare := fPlotView.Focus;
  1320.             { set the world up to focus all drawing in the PlotView }
  1321.             
  1322.         fPlotView.GetQDFrame(plotRect);
  1323.             { the design says we draw into the available frame }
  1324.  
  1325.         DrawPicture(fPlotPICT, plotRect);
  1326.             { Draw the PICT in the PlotView }
  1327.             
  1328.         dontCare := SELF.Focus;
  1329.             { shift the focus back to us }
  1330.  
  1331.     END;
  1332.  
  1333.  
  1334. {---------------------------------------------------}
  1335. PROCEDURE TPlotDialog.EachSubView(PROCEDURE DoToSubView(theSubView: TView));
  1336. BEGIN
  1337.     { We do not want all of our clever dialog elements printing so lets
  1338.       skip them when printing }
  1339.     IF NOT gPrinting THEN
  1340.         INHERITED EachSubView(DoToSubView);
  1341. END;
  1342.  
  1343. {---------------------------------------------------}
  1344. PROCEDURE TPlotDialog.PlotNDrawPICT;
  1345.     VAR
  1346.         plotRect    : Rect;
  1347.         solveRect    : Rect;
  1348.         saveClip     : RgnHandle;
  1349.         pstate        : PenState;
  1350.         dontCare    : BOOLEAN;
  1351.         aFontNum    : INTEGER;
  1352.         
  1353.     BEGIN
  1354.     
  1355.         GetPlotValues;
  1356.             { get current values from the view }
  1357.         fPlotDoc.SolveQuadratic;
  1358.             { for the parameters retrieved, setup the solution values }
  1359.         
  1360.  
  1361.         IF fPlotPICT <> NIL THEN
  1362.                 KillPicture(fPlotPICT);
  1363.         
  1364.         dontCare := fPlotView.Focus;
  1365.         fPlotView.GetQDExtent(plotRect);
  1366.             { change MacApp’s focus to the plotview
  1367.               to properly get our plot rect}
  1368.         dontCare := SELF.Focus;
  1369.             { and of course lets set the FOCUS back to us.
  1370.               The above process of setting up plotRect might have
  1371.               been better handleed by declaring an fRect in plotview
  1372.               and having the resize method of plotview keep it up to date}
  1373.               
  1374.         fPlotPICT := OpenPicture(plotRect);
  1375.  
  1376.         saveClip := NewRgn;
  1377.         FailNIL(SaveClip);
  1378.         GetClip(SaveClip);
  1379.  
  1380.         GetPenState(pstate);
  1381.         
  1382.         { setup the font info for our plot }
  1383.         {$Push} {$H-}
  1384.         GetFNum(fPlotDoc.fPlotSpecs.theTextFont, aFontNum);
  1385.         {$H+}
  1386.         TextFont(aFontNum);
  1387.         TextSize(fPlotDoc.fPlotSpecs.theTextSize);
  1388.         TextFace(fPlotDoc.fPlotSpecs.theTextFace);
  1389.             { we also have: theTextColor, theJustification, theBackColor
  1390.               that we might want to do something with in the future }
  1391.         TextMode(srcOr);
  1392.             
  1393.         {Begin MacDraw Document PICT}
  1394.         PicComment(picDwgBeg, 0, NIL);        
  1395.             PicComment(picGrpBeg, 0, NIL);
  1396.  
  1397.             fPlotView.AddToPict(plotRect);
  1398.  
  1399.             solveRect := fSolutionView.fSolveRect;
  1400.                 { get our plot rect, we know that this is a fixed rect}
  1401.                 
  1402.             offsetRect(solveRect,4{border},plotRect.Bottom-(solveRect.Bottom+4{border}));
  1403.                 { slide the textbox on down to the bottom of the view area
  1404.                   this assumes that the solution textbox is smaller than the plotRect}
  1405.  
  1406.             fSolutionView.AddToPict(solveRect);
  1407.  
  1408.             PicComment(PicGrpEnd, 0, NIL);
  1409.         PicComment(picDwgEnd, 0, NIL);         
  1410.  
  1411.         ClosePicture;
  1412.  
  1413.         SetPenState(pstate);
  1414.         SetClip(saveClip);
  1415.  
  1416.         DisposeRgn(saveClip);
  1417.  
  1418.         ForceRedraw;
  1419.             { make the dialog rect invalid }
  1420.     END;
  1421.     
  1422. {---------------------------------------------------}
  1423. PROCEDURE TPlotDialog.GetPlotValues;
  1424.  
  1425.     BEGIN
  1426.     
  1427.     fPlotDoc.faParam := TExtendedText(FindSubView('cofA')).GetValue;
  1428.     fPlotDoc.fbParam := TExtendedText(FindSubView('cofB')).GetValue;
  1429.     fPlotDoc.fcParam := TExtendedText(FindSubView('cofC')).GetValue;
  1430.     
  1431.     fPlotDoc.fstepParam := TExtendedText(FindSubView('step')).GetValue;
  1432.     fPlotDoc.fxParam := TNumberText(FindSubView('xAxs')).GetValue;
  1433.     fPlotDoc.fyParam := TNumberText(FindSubView('yAxs')).GetValue;
  1434.     
  1435.     END;
  1436.  
  1437. {---------------------------------------------------}
  1438. PROCEDURE TPlotView.GetQDFrame(VAR frameRect:Rect);
  1439.     VAR
  1440.         extent:             VRect;
  1441.  
  1442. BEGIN
  1443.     GetFrame(extent);
  1444.     ViewToQDRect(extent, frameRect);
  1445. END;
  1446.  
  1447. {---------------------------------------------------}
  1448. PROCEDURE TPlotView.AddToPict(picRect:Rect);
  1449.     CONST
  1450.         AxisLabelIndent = 4;
  1451.         
  1452.     TYPE
  1453.         Widpt  = Point;
  1454.         WidPtr = ^WidPt;
  1455.         WidHdl = ^WidPtr;
  1456.  
  1457.     VAR
  1458.         x, y         : Real;
  1459.         a,b,c        : Real;
  1460.         step        : Real;
  1461.         halfXScale    : Real;
  1462.         xPictScale    : Real;
  1463.         yPictScale    : Real;        
  1464.  
  1465.         lastPt        : Point;
  1466.         thisPt        : Point;
  1467.         xScale        : INTEGER;
  1468.         yScale        : INTEGER;
  1469.         CenterHorz    : INTEGER;
  1470.         CenterVert    : INTEGER;
  1471.         PictHorz    : INTEGER;
  1472.         PictVert    : INTEGER;
  1473.         
  1474.         leading        : INTEGER;
  1475.         fInfo         : FontInfo;
  1476.         Width         : Widhdl;
  1477.         axisLabel    : str255;
  1478.         
  1479.         newColor    : RGBColor;
  1480.         oldBack        : RGBColor;
  1481.         oldFore        : RGBColor;
  1482.         
  1483.         drawLine    : BOOLEAN;
  1484.                 
  1485.     BEGIN
  1486.     
  1487.         Width := Widhdl(NewHandle(sizeof(widpt)));
  1488.         Width^^.h := 10;
  1489.         Width^^.v := 1;
  1490.  
  1491.         GetFontInfo(fInfo);
  1492.         leading := fInfo.descent + fInfo.ascent + fInfo.leading;
  1493.             
  1494.         WITH fPlotDoc DO 
  1495.             BEGIN
  1496.             { retrieve the length of our Axis }
  1497.             xScale := fxParam;
  1498.             yScale := fyParam;
  1499.             
  1500.             { retrieve the coeficients }
  1501.             a := faParam;
  1502.             b := fbParam;
  1503.             c := fcParam;
  1504.             step := fStepParam;
  1505.             END;
  1506.             
  1507.         ClipRect(picRect);
  1508.  
  1509.         GetForeColor(oldFore);
  1510.         GetBackColor(oldBack);
  1511.  
  1512.         PenNormal;
  1513.         
  1514.  
  1515. {Draw Graph Boundry}
  1516.         PicComment(picGrpBeg, 0, NIL);
  1517.  
  1518.         newColor := fPlotDoc.fPlotSpecs.theBackColor;
  1519.         RGBBackColor(newColor);
  1520.         
  1521.         PicComment(SetLineWidth, GetHandleSize(Handle(Width)), Handle(Width));
  1522.         FillRect(picRect, white);
  1523.         FrameRect(picRect);
  1524.  
  1525.  
  1526. {Two Axis}
  1527.         newColor := fPlotDoc.fPlotSpecs.theAxisColor;
  1528.         RGBForeColor(newColor);
  1529.  
  1530.         { find the height of our View that we will draw into }
  1531.         PictHorz := picRect.right  - picRect.left;
  1532.         PictVert := picRect.bottom - picRect.top;
  1533.         
  1534.         { find the center coordinates of the view }
  1535.         CenterHorz := PictHorz DIV 2;
  1536.         CenterVert := PictVert DIV 2;
  1537.         
  1538.         PicComment(picGrpBeg, 0, NIL);
  1539.             moveto(0, CenterVert);
  1540.             line( PictHorz, 0);
  1541.             moveto(CenterHorz, 0);
  1542.             line(0, PictVert);
  1543.         PicComment(picGrpEnd, 0, NIL);
  1544.  
  1545.  
  1546.         newColor := fPlotDoc.fPlotSpecs.theGraphColor;
  1547.         RGBForeColor(newColor);
  1548.         
  1549. {Axis Text}
  1550.         { Place -X axis label to the lowerleft of the axis line }
  1551.         moveto(AxisLabelIndent, CenterVert + leading);
  1552.         NumToString(-xScale,axisLabel);
  1553.         DrawString(axisLabel);
  1554.  
  1555.         { Place +Y axis label to the topleft of the axis line }
  1556.         NumToString(yScale,axisLabel);
  1557.         moveto(CenterHorz - (StringWidth(axisLabel) + AxisLabelIndent), leading);
  1558.         DrawString(axisLabel);
  1559.  
  1560.         { Place +X axis label to the lowerright of the axis line }
  1561.         NumToString(xScale,axisLabel);
  1562.         moveto(PictHorz - (StringWidth(axisLabel) + AxisLabelIndent),
  1563.                CenterVert + leading);
  1564.         DrawString(axisLabel);
  1565.  
  1566.         { Place -Y axis label to the lowerleft of the axis line }
  1567.         NumToString(-yScale,axisLabel);
  1568.         moveto(CenterHorz - (StringWidth(axisLabel) + AxisLabelIndent),
  1569.                 PictVert - leading);
  1570.         DrawString(axisLabel);
  1571.  
  1572. {The Plot}        
  1573.         { calculate a scale factor for the PICT’s axis in the view }
  1574.         xPictScale := PictHorz / xScale;
  1575.         yPictScale := PictVert / yScale;
  1576.         
  1577.         
  1578.         { calculate our starting x,y point }
  1579.         halfXScale := xScale / 2;
  1580.         x := -halfXScale;
  1581.         y := a * x * x + (b * x) + c;
  1582.         
  1583.         { Scale it into the PICT’s (and PostScript’s) view space} 
  1584.         thisPt.h := integer(round(x * xPictScale))+CenterHorz;
  1585.         thisPt.v := integer(round(-y * yPictScale))+CenterVert;
  1586.  
  1587.         { The original did not clip lines so here is a feeble stab at
  1588.           find wher to stop and start drawing.
  1589.              LOOP until we reach all x values:
  1590.                  1. Find our first visible line segment
  1591.                 2. Plot until it disappears
  1592.                 3. Find a suitable end point
  1593.          }
  1594.          
  1595.         WHILE (NOT PtInRect(thisPt,picRect)) &  (x <= halfXscale) DO
  1596.             BEGIN
  1597.             x := x + step;
  1598.             y := a * x * x + (b * x) + c;
  1599.             thisPt.h := integer(round(x * xPictScale))+CenterHorz;
  1600.             thisPt.v := integer(round(-y * yPictScale))+CenterVert;
  1601.             END;
  1602.         
  1603.         moveTo(thisPt.h,thisPt.v);
  1604.         drawLine := TRUE;
  1605.         
  1606.         PicComment(picGrpBeg, 0, NIL);
  1607.  
  1608.             REPEAT
  1609.                 x := x + step;
  1610.                 y := (a * x * x) + (b * x) + c;
  1611.                 thisPt.h := integer(round(x * xPictScale))+CenterHorz;
  1612.                 thisPt.v := integer(round(-y * yPictScale))+CenterVert;
  1613.                 IF NOT PtInRect(thisPt,picRect) THEN
  1614.                     drawLine := FALSE
  1615.                 ELSE
  1616.                     BEGIN
  1617.                     IF drawLine THEN
  1618.                         LineTo(thisPt.h,thisPt.v)
  1619.                     ELSE
  1620.                         BEGIN
  1621.                         drawLine := TRUE;
  1622.                         moveTo(thisPt.h,thisPt.v)
  1623.                         END
  1624.                     END;
  1625.                     
  1626. writeln('h:',thisPt.h,' v:',thisPt.v);
  1627.  
  1628.             UNTIL x >= halfXScale;
  1629.             
  1630.         PicComment(picGrpEnd, 0, NIL);
  1631.  
  1632.         RGBForeColor(oldFore);
  1633.         RGBBackColor(oldBack);
  1634.         
  1635.         PicComment(PicGrpEnd, 0, NIL); {of select all objects}
  1636.  
  1637.     END;
  1638.  
  1639. {---------------------------------------------------}
  1640.  
  1641. PROCEDURE TPlotView.Resize(width, height: VCoordinate; invalidate: BOOLEAN); OVERRIDE;
  1642. BEGIN
  1643. invalidate := TRUE;
  1644. INHERITED Resize(width, height, invalidate);
  1645. ForceRedraw;
  1646. END;
  1647.  
  1648.  
  1649. {---------------------------------------------------}
  1650. { Adds the text box containing the Quadratic equation solution to our PICT. }
  1651.  
  1652. PROCEDURE TSolutionView.AddToPict(picRect: Rect);
  1653.  
  1654.     CONST
  1655.         k1stLine = 1; k2ndLine = 2; k3rdLine = 3;
  1656.         k4thLine = 4; k5thLine = 5;
  1657.         
  1658.         kLeftJust = 1;
  1659.         kIndent = 2;
  1660.         
  1661.     TYPE
  1662.         Widpt  = Point;
  1663.         WidPtr = ^WidPt;
  1664.         WidHdl = ^WidPtr;
  1665.  
  1666.         TTxtPicRec = PACKED RECORD
  1667.                 tJus : Byte;
  1668.                 tFlip : Byte;
  1669.                 tRot : Integer;
  1670.                 tLine : Byte;
  1671.                 tCmnt : Byte;
  1672.             END;
  1673.  
  1674.     VAR
  1675.         TextClipRgn : RgnHandle;
  1676.         TxtPicRec     : TTxtPicRec;
  1677.         TxtPicPtr     : QDPtr;
  1678.         TxtPicHdl     : QDHandle;
  1679.         Width        : WidHdl;
  1680.         
  1681.         clipBox        : Rect;
  1682.         boxTop        : INTEGER;
  1683.         boxLeft        : INTEGER;
  1684.         leading        : INTEGER;
  1685.         fInfo         : FontInfo;
  1686.         LineNo        : INTEGER;
  1687.  
  1688.         a,b,c        : Real;
  1689.         x1,x2        : Real;
  1690.         z1,z2        : Real;
  1691.         
  1692.         newColor    : RGBColor;
  1693.                 
  1694. BEGIN
  1695.  
  1696.     WITH fPlotDoc DO 
  1697.         BEGIN
  1698.         { retrieve the Solution }
  1699.         x1 := f1stRoot;
  1700.         x2 := f2ndRoot;
  1701.         
  1702.         { retrieve the coeficients }
  1703.         a := faParam;
  1704.         b := fbParam;
  1705.         c := fcParam;
  1706.         END;
  1707.         
  1708.     Width := Widhdl(NewHandle(sizeof(widpt)));
  1709.     Width^^.h := 10;
  1710.     Width^^.v := 1;
  1711.         
  1712.     GetFontInfo(fInfo);
  1713.     leading := fInfo.descent + fInfo.ascent + fInfo.leading;
  1714.  
  1715.     PicComment(picGrpBeg, 0, NIL);
  1716.     
  1717.     {Box }
  1718.         PicComment(picGrpBeg, 0, NIL);
  1719.             PicComment(SetLineWidth, GetHandleSize(Handle(Width)), Handle(Width));
  1720.             fillRect(picRect, white); 
  1721.             frameRect(picRect);
  1722.         PicComment(picGrpEnd, 0, NIL); {of box}
  1723.  
  1724.         TextClipRgn := NewRgn;
  1725.         FailNil(TextClipRgn);
  1726.         
  1727.         GetClip(TextClipRgn);
  1728.         clipBox := picRect;
  1729.         ClipRect(clipBox);
  1730.         
  1731.     newColor := fPlotDoc.fPlotSpecs.theTextColor;
  1732.     RGBForeColor(newColor);
  1733.  
  1734.     {Box Text}
  1735.         { setup our Text Comment Handle }
  1736.         TxtPicPtr := @TxtPicRec;
  1737.         TxtPicHdl := @TxtPicPtr;
  1738.         TxtPicRec.tJus  := kLeftJust;
  1739.         TxtPicRec.tFlip := 0;    {no flip}
  1740.         TxtPicRec.tRot  := 0;    {no rotation}
  1741.         TxtPicRec.tLine := 2;    {1 1/2 spacing}
  1742.         
  1743.         {put the Comment into our PICT}
  1744.         PicComment(TextBegin, sizeof(TTxtPicRec), Handle(TxtPicHdl));
  1745.  
  1746.             { Add the BOX text to the PICT }
  1747.                 boxTop :=  picRect.top;
  1748.                 boxLeft:=  picRect.Left;
  1749.                 
  1750.                 MoveTo(boxLeft + kIndent, boxTop + (k1stLine * leading));
  1751.                 DrawString(CONCAT('y=ax^2 + bx + c', chr(13)));
  1752.                 
  1753.                 MoveTo(boxLeft + kIndent, boxTop + (k2ndLine * leading));
  1754.                 DrawString(CONCAT(  'a=', Real2Str(a,1),
  1755.                                   ', b=', Real2Str(b,1),
  1756.                                   ', c=', Real2Str(c,1), chr(13)));
  1757.                                   
  1758.                 { The solution text is next }
  1759.                 MoveTo(boxLeft + kIndent, boxTop + (k3rdLine * leading));
  1760.                 DrawString(CONCAT(  'x1=', Real2Str(x1,3),
  1761.                                   ', x2=', Real2Str(x2,3), chr(13)));
  1762.  
  1763.                 { Display the kind of Quadratic soultion we have }
  1764.                 MoveTo(boxLeft + kIndent, boxTop + (k4thLine * leading));
  1765.                 CASE fPlotDoc.fRootType OF
  1766.                     RealRoots : 
  1767.                         DrawString(CONCAT('Two Real Roots, x1, x2', chr(13)));
  1768.                     SingleSolution : 
  1769.                         DrawString(CONCAT('Double Root', chr(13)));
  1770.                     ComplexRoot : 
  1771.                         DrawString(CONCAT('Two Complex Roots ', chr(13)));
  1772.                     OTHERWISE
  1773.                         ;
  1774.                 END;
  1775.                 
  1776.                 { Calculate the slope and add the string it to the PICT}
  1777.                 WITH fPlotDoc DO
  1778.                 BEGIN
  1779.                 z1 := -b / (2 * a);
  1780.                 z2 := (4 * a * c - (b * b)) / (4 * b);
  1781.                 END;
  1782.                 
  1783.                 MoveTo(boxLeft + kIndent, boxTop + (k5thLine * leading));
  1784.                 DrawString(CONCAT('Slope 0 is (', Real2Str(z1,1),
  1785.                                      ',', Real2Str(z2,1),')', chr(13)));
  1786.                 
  1787.         { All done with our text    }            
  1788.         PicComment(TextEnd, 0, NIL);
  1789.         
  1790.     PicComment(PicGrpEnd, 0, NIL); {of Box & text}
  1791.     
  1792.     DisposHandle(Handle(width));
  1793.     DisposeRgn(TextClipRgn);
  1794.  
  1795. END;
  1796.  
  1797.  
  1798.  
  1799. {---------------------------------------------------}
  1800. PROCEDURE TPStyleCmd.DoIt;
  1801.     BEGIN
  1802.     fPlotDialog.fPlotDoc.fPlotSpecs := fNewPlotSPecs;
  1803.     END;
  1804.  
  1805.  
  1806. {---------------------------------------------------}
  1807. PROCEDURE TPStyleCmd.ReDoIt;
  1808.     BEGIN
  1809.     fPlotDialog.fPlotDoc.fPlotSpecs := fNewPlotSPecs;
  1810.     END;
  1811.  
  1812.  
  1813. {---------------------------------------------------}
  1814. PROCEDURE TPStyleCmd.UnDoIt;
  1815.     BEGIN
  1816.     fPlotDialog.fPlotDoc.fPlotSpecs := fOldPlotSPecs;
  1817.     END;
  1818.  
  1819.  
  1820. {---------------------------------------------------}
  1821. PROCEDURE TPStyleCmd.IPStyleCmd(itsPlotDialog: TPlotDialog;itsNewStyle: PlotSpecsPtr;itsCmdNumber: CmdNumber);
  1822.  
  1823.     BEGIN
  1824.     ICommand(itsCmdNumber, itsPlotDialog.fPlotDoc, itsPlotDialog, NIL);
  1825.  
  1826.     fPlotDialog := itsPlotDialog;
  1827.     fOldPlotSPecs := fPlotDialog.fPlotDoc.fPlotSpecs;
  1828.     fNewPlotSPecs := itsNewStyle^;
  1829.     END;
  1830.     
  1831. END.    
  1832.  
  1833. (*
  1834. {---------------------------------------------------}
  1835.     { T H E   M A I N   P R O G R A M }
  1836.  
  1837.     BEGIN
  1838.  
  1839.     InitUMacApp(8);                     {Initialize the Toolbox, making 8 calls to
  1840.                                                  MoreMasters:}
  1841.     InitPrinting;                        {Initialize the UPrinting unit:}
  1842.  
  1843.     NEW(gPlotApplication);                {Allocate a new TPlotApplication object:}
  1844.     FailNIL(gPlotApplication);
  1845.     gPlotApplication.IPlotApplication(kFileType); {Initialize that new object:}
  1846.  
  1847.     gPlotApplication.Run;                {Run the application. When it's done, exit.}
  1848.     END.
  1849. *)